<template>
  <div></div>
</template>

<script setup lang="ts">
  import { LowSync } from 'lowdb'
  import { DataFileSync, JSONFileSync, JSONFileSyncPreset } from 'lowdb/node'
  import { resolve } from 'path'
  import lodash from 'lodash'
  import crypto from 'crypto'

  function resolvePath(fileName: string) {
    return resolve(process.cwd(), 'db', fileName)
  }

  interface User {
    id: number
    username: string
    age: number
    userType: string
    email: string
    sort: number
  }

  interface Data {
    users: User[]
  }
  // 1.lowdb 的基本使用
  {
    // 初始化json文件，创建或读取
    const defaultData: Data = { users: [] }
    const db = JSONFileSyncPreset(resolvePath('demo.json'), defaultData)

    // 添加数据
    function addUser(user: Omit<User, 'id'>) {
      let id = db.data.users.length + 1

      // 两步
      /* db.data.users.push({ id, ...user })
    db.write() */

      db.update(({ users }) => {
        db.data.users.push({ id, ...user })
      })
    }

    // 删除数据
    function delUser(id: number) {
      db.update(({ users }) => {
        users.splice(
          users.findIndex((item) => item.id === id),
          1
        )
      })
    }

    // addUser({ username: 'kunkun', age: 18, userType: 'admin', sort: 10 })
    // addUser({ username: '唔西迪西', age: 20, userType: 'admin', sort: 12 })
    // delUser(1)

    // 修改数据
    function updateUser(id: number, user: Partial<User>) {
      db.update(({ users }) => {
        const index = users.findIndex((item) => item.id === id)
        users[index] = { ...users[index], ...user }
      })
    }

    // updateUser(1, { username: '坤坤', userType: 'admin' })

    // 查询数据
    function getUser(id: number) {
      return db.data.users.find((item) => item.id === id)
    }

    // let user = getUser(1)
    // console.log(user)

    // 查询所有数据
    function getAllUser() {
      return db.data.users
    }

    /* let users = getAllUser()
  console.log(users) */
  }

  // 2.使用 lodash 扩展 lowdb
  {
    class LowWithLodash<T> extends LowSync<T> {
      // lodash.chain：创建一个能够被链式调用的 lodash 对象
      chain: lodash.ExpChain<this['data']> = lodash.chain(this).get('data')
    }

    // 初始化默认数据
    const defaultData: Data = { users: [] }
    // 创建一个适配器
    const adapter = new JSONFileSync<Data>(resolvePath('demo2.json'))
    // 实例化
    const db = new LowWithLodash(adapter, defaultData)
    // 读取文件
    db.read()

    // 添加数据
    function addUser(user: Omit<User, 'id'>) {
      let id = db.data.users.length + 1
      db.chain
        .get('users')
        .push({ id, ...user })
        .value()

      db.write()
    }

    // addUser({ username: 'kunkun', age: 18, userType: 'user', sort: 10 })
    // addUser({ username: '唔西迪西', age: 20, userType: 'admin', sort: 12 })

    // 删除数据
    function delUser(id: number) {
      db.chain.get('users').remove({ id: id }).value()
      db.write()
    }

    // 清空数据
    function clearUser() {
      db.chain.set('users', []).value()
      db.write()
    }
    // clearUser()

    // 修改数据
    function updateUser(id: number, user: Partial<Omit<User, 'id'>>) {
      db.chain.get('users').find({ id: id }).assign(user).value()
      db.write()
    }
    updateUser(1, { username: '坤坤', userType: 'admin' })

    // 查询数据
    function getUser(id: number) {
      return db.chain.get('users').find({ id }).value()
    }

    // let user = getUser(1)
    // console.log(user, 'user')

    // 查询所有数据
    function getAllUser() {
      return db.chain.get('users').value()
    }

    // let users = getAllUser()

    function getLastUser() {
      return db.chain.get('users').last().value()
    }

    console.log(getLastUser(), 'last')
    // console.log(users, 'users')
  }

  // 3.加密解密
  {
    // 算法
    const algorithm = 'aes-256-cbc'
    // 秘钥
    const key = crypto.scryptSync('secret', 'salt', 32)
    // 初始化向量
    const iv = Buffer.alloc(16, 6)

    // 加密数据
    function encrypt(data: string) {
      // 创建加密对象
      const cipher = crypto.createCipheriv(algorithm, key, iv)
      // 对数据进行加密
      let encrypted = cipher.update(data, 'utf8')
      // 加密结束
      encrypted = Buffer.concat([encrypted, cipher.final()])
      // 生成 16 进制密文
      let result = encrypted.toString('hex')
      return result
    }

    // 解密
    function decrypt(text: string) {
      // 创建解密对象
      const decipher = crypto.createDecipheriv(algorithm, key, iv)
      // 进行解密
      let decrypted = decipher.update(text, 'hex')
      // 解密结束
      decrypted = Buffer.concat([decrypted, decipher.final()])
      let result = decrypted.toString()
      return result
    }

    const defaultData: Data = { users: [] }
    const adapter = new DataFileSync<Data>(resolvePath('demo2.json'), {
      parse: (data) => {
        return JSON.parse(decrypt(data))
      },
      stringify: (data) => {
        return encrypt(JSON.stringify(data))
      }
    })

    const db = new LowSync(adapter, defaultData)
    db.read()

    function addUser(user: Omit<User, 'id'>) {
      let id = db.data.users.length + 1
      db.data.users.push({ id, ...user })
      db.write()
    }

    // addUser({ username: 'kunkun', age: 18, userType: 'user', sort: 10 })
    // addUser({ username: '唔西迪西', age: 20, userType: 'user', sort: 12 })

    function getUser(id: number) {
      return db.data.users.find((item) => item.id === id)
    }

    let user = getUser(1)
    console.log(user, 'user')
  }
</script>

<style scoped></style>
